home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / site-packages / impacket / nmb.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2006-06-30  |  27KB  |  899 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. import os
  5. import sys
  6. import socket
  7. import string
  8. import re
  9. import select
  10. import errno
  11. from random import randint
  12. from struct import *
  13. CVS_REVISION = '$Revision: 1.4 $'
  14. INADDR_ANY = ''
  15. BROADCAST_ADDR = '<broadcast>'
  16. NETBIOS_NS_PORT = 137
  17. NETBIOS_SESSION_PORT = 139
  18. SMB_SESSION_PORT = 445
  19. NODE_B = 0
  20. NODE_P = 8192
  21. NODE_M = 16384
  22. NODE_RESERVED = 24576
  23. NODE_GROUP = 32768
  24. NODE_UNIQUE = 0
  25. TYPE_UNKNOWN = 1
  26. TYPE_WORKSTATION = 0
  27. TYPE_CLIENT = 3
  28. TYPE_SERVER = 32
  29. TYPE_DOMAIN_MASTER = 27
  30. TYPE_MASTER_BROWSER = 29
  31. TYPE_BROWSER = 30
  32. TYPE_NETDDE = 31
  33. OPCODE_QUERY = 0
  34. OPCODE_REGISTRATION = 5
  35. OPCODE_RELEASE = 6
  36. OPCODE_WACK = 7
  37. OPCODE_REFRESH = 8
  38. OPCODE_REQUEST = 0
  39. OPCODE_RESPONSE = 16
  40. NM_FLAGS_BROADCAST = 1
  41. NM_FLAGS_UNICAST = 0
  42. NM_FLAGS_RA = 8
  43. NM_FLAGS_RD = 16
  44. NM_FLAGS_TC = 32
  45. NM_FLAGS_AA = 64
  46. QUESTION_TYPE_NB = 32
  47. QUESTION_TYPE_NBSTAT = 33
  48. QUESTION_CLASS_IN = 1
  49. RR_TYPE_A = 1
  50. RR_TYPE_NS = 2
  51. RR_TYPE_NULL = 10
  52. RR_TYPE_NB = 32
  53. RR_TYPE_NBSTAT = 33
  54. RR_CLASS_IN = 1
  55. RCODE_FMT_ERR = 1
  56. RCODE_SRV_ERR = 2
  57. RCODE_IMP_ERR = 4
  58. RCODE_RFS_ERR = 5
  59. RCODE_ACT_ERR = 6
  60. RCODE_CFT_ERR = 7
  61. NAME_FLAGS_PRM = 512
  62. NAME_FLAGS_ACT = 1024
  63. NAME_FLAG_CNF = 2048
  64. NAME_FLAG_DRG = 4096
  65. NAME_TYPES = {
  66.     TYPE_UNKNOWN: 'Unknown',
  67.     TYPE_WORKSTATION: 'Workstation',
  68.     TYPE_CLIENT: 'Client',
  69.     TYPE_SERVER: 'Server',
  70.     TYPE_MASTER_BROWSER: 'Master Browser',
  71.     TYPE_BROWSER: 'Browser Server',
  72.     TYPE_DOMAIN_MASTER: 'Domain Master',
  73.     TYPE_NETDDE: 'NetDDE Server' }
  74. NETBIOS_SESSION_MESSAGE = 0
  75. NETBIOS_SESSION_REQUEST = 129
  76. NETBIOS_SESSION_POSITIVE_RESPONSE = 130
  77. NETBIOS_SESSION_NEGATIVE_RESPONSE = 131
  78. NETBIOS_SESSION_RETARGET_RESPONSE = 132
  79. NETBIOS_SESSION_KEEP_ALIVE = 133
  80.  
  81. def strerror(errclass, errcode):
  82.     if errclass == ERRCLASS_OS:
  83.         return ('OS Error', os.strerror(errcode))
  84.     elif errclass == ERRCLASS_QUERY:
  85.         return ('Query Error', QUERY_ERRORS.get(errcode, 'Unknown error'))
  86.     elif errclass == ERRCLASS_SESSION:
  87.         return ('Session Error', SESSION_ERRORS.get(errcode, 'Unknown error'))
  88.     else:
  89.         return ('Unknown Error Class', 'Unknown Error')
  90.  
  91.  
  92. class NetBIOSError(Exception):
  93.     pass
  94.  
  95.  
  96. class NetBIOSTimeout(Exception):
  97.     
  98.     def __init__(self, message = 'The NETBIOS connection with the remote host timed out.'):
  99.         Exception.__init__(self, message)
  100.  
  101.  
  102.  
  103. class NBResourceRecord:
  104.     
  105.     def __init__(self, data = 0):
  106.         self._data = data
  107.         
  108.         try:
  109.             if self._data:
  110.                 self.rr_name = re.split('\x00', data)[0]
  111.                 offset = len(self.rr_name) + 1
  112.                 self.rr_type = unpack('>H', self._data[offset:offset + 2])[0]
  113.                 self.rr_class = unpack('>H', self._data[offset + 2:offset + 4])[0]
  114.                 self.ttl = unpack('>L', self._data[offset + 4:offset + 8])[0]
  115.                 self.rdlength = unpack('>H', self._data[offset + 8:offset + 10])[0]
  116.                 self.rdata = data[offset + 10:self.rdlength]
  117.                 offset = self.rdlength - 2
  118.                 self.unit_id = data[offset:offset + 6]
  119.             else:
  120.                 self.rr_name = ''
  121.                 self.rr_type = 0
  122.                 self.rr_class = 0
  123.                 self.ttl = 0
  124.                 self.rdlength = 0
  125.                 self.rdata = ''
  126.                 self.unit_id = ''
  127.         except Exception:
  128.             e = None
  129.             raise NetBIOSError('Wrong packet format ')
  130.  
  131.  
  132.     
  133.     def set_rr_name(self, name):
  134.         self.rr_name = name
  135.  
  136.     
  137.     def set_rr_type(self, name):
  138.         self.rr_type = name
  139.  
  140.     
  141.     def set_rr_class(self, cl):
  142.         self_rr_class = cl
  143.  
  144.     
  145.     def set_ttl(self, ttl):
  146.         self.ttl = ttl
  147.  
  148.     
  149.     def set_rdata(self, rdata):
  150.         self.rdata = rdata
  151.         self.rdlength = len(rdata)
  152.  
  153.     
  154.     def get_unit_id(self):
  155.         return self.unit_id
  156.  
  157.     
  158.     def get_rr_name(self):
  159.         return self.rr_name
  160.  
  161.     
  162.     def get_rr_class(self):
  163.         return self.rr_class
  164.  
  165.     
  166.     def get_ttl(self):
  167.         return self.ttl
  168.  
  169.     
  170.     def get_rdlength(self):
  171.         return self.rdlength
  172.  
  173.     
  174.     def get_rdata(self):
  175.         return self.rdata
  176.  
  177.     
  178.     def rawData(self):
  179.         return self.rr_name + pack('!HHLH', self.rr_type, self.rr_class, self.ttl, self.rdlength) + self.rdata
  180.  
  181.  
  182.  
  183. class NBNodeStatusResponse(NBResourceRecord):
  184.     
  185.     def __init__(self, data = 0):
  186.         NBResourceRecord.__init__(self, data)
  187.         self.num_names = 0
  188.         self.node_names = []
  189.         self.statstics = ''
  190.         self.mac = '00-00-00-00-00-00'
  191.         
  192.         try:
  193.             if data:
  194.                 self._data = self.get_rdata()
  195.                 self.num_names = unpack('>B', self._data[:1])[0]
  196.                 offset = 1
  197.                 for i in range(0, self.num_names):
  198.                     name = self._data[offset:offset + 15]
  199.                     (type, flags) = unpack('>BH', self._data[offset + 15:offset + 18])
  200.                     offset += 18
  201.                     self.node_names.append(NBNodeEntry(name, type, flags))
  202.                 
  203.                 self.set_mac_in_hexa(self.get_unit_id())
  204.         except Exception:
  205.             e = None
  206.             raise NetBIOSError('Wrong packet format ')
  207.  
  208.  
  209.     
  210.     def set_mac_in_hexa(self, data):
  211.         data_aux = ''
  212.         for d in data:
  213.             if data_aux == '':
  214.                 data_aux = '%02x' % ord(d)
  215.                 continue
  216.             data_aux += '-%02x' % ord(d)
  217.         
  218.         self.mac = string.upper(data_aux)
  219.  
  220.     
  221.     def get_num_names(self):
  222.         return self.num_names
  223.  
  224.     
  225.     def get_mac(self):
  226.         return self.mac
  227.  
  228.     
  229.     def set_num_names(self, num):
  230.         self.num_names = num
  231.  
  232.     
  233.     def get_node_names(self):
  234.         return self.node_names
  235.  
  236.     
  237.     def add_node_name(self, node_names):
  238.         self.node_names.append(node_names)
  239.         self.num_names += 1
  240.  
  241.     
  242.     def rawData(self):
  243.         res = pack('!B', self.num_names)
  244.         for i in range(0, self.num_names):
  245.             res += self.node_names[i].rawData()
  246.         
  247.  
  248.  
  249.  
  250. class NBPositiveNameQueryResponse(NBResourceRecord):
  251.     
  252.     def __init__(self, data = 0):
  253.         NBResourceRecord.__init__(self, data)
  254.         self.add_entries = []
  255.         if data:
  256.             self._data = self.get_rdata()
  257.         
  258.  
  259.  
  260.  
  261. class NetBIOSPacket:
  262.     ''' This is a packet as defined in RFC 1002 '''
  263.     
  264.     def __init__(self, data = 0):
  265.         self.name_trn_id = 0
  266.         self.opcode = 0
  267.         self.nm_flags = 0
  268.         self.rcode = 0
  269.         self.qdcount = 0
  270.         self.ancount = 0
  271.         self.nscount = 0
  272.         self.arcount = 0
  273.         self.questions = ''
  274.         self.answers = ''
  275.         if data == 0:
  276.             self._data = ''
  277.         else:
  278.             
  279.             try:
  280.                 self._data = data
  281.                 self.opcode = ord(data[2]) >> 3
  282.                 self.nm_flags = (ord(data[2]) & 3) << 4 | (ord(data[3]) & 240) >> 4
  283.                 self.name_trn_id = unpack('>H', self._data[:2])[0]
  284.                 self.rcode = ord(data[3]) & 15
  285.                 self.qdcount = unpack('>H', self._data[4:6])[0]
  286.                 self.ancount = unpack('>H', self._data[6:8])[0]
  287.                 self.nscount = unpack('>H', self._data[8:10])[0]
  288.                 self.arcount = unpack('>H', self._data[10:12])[0]
  289.                 self.answers = self._data[12:]
  290.             except Exception:
  291.                 e = None
  292.                 raise NetBIOSError('Wrong packet format ')
  293.  
  294.  
  295.     
  296.     def set_opcode(self, opcode):
  297.         self.opcode = opcode
  298.  
  299.     
  300.     def set_trn_id(self, trn):
  301.         self.name_trn_id = trn
  302.  
  303.     
  304.     def set_nm_flags(self, nm_flags):
  305.         self.nm_flags = nm_flags
  306.  
  307.     
  308.     def set_rcode(self, rcode):
  309.         self.rcode = rcode
  310.  
  311.     
  312.     def addQuestion(self, question, qtype, qclass):
  313.         self.qdcount = self.qdcount + 1
  314.         self.questions += question + pack('!HH', qtype, qclass)
  315.  
  316.     
  317.     def get_trn_id(self):
  318.         return self.name_trn_id
  319.  
  320.     
  321.     def get_rcode(self):
  322.         return self.rcode
  323.  
  324.     
  325.     def get_nm_flags(self):
  326.         return self.name_trn_id
  327.  
  328.     
  329.     def get_opcode(self):
  330.         return self.opcode
  331.  
  332.     
  333.     def get_qdcount(self):
  334.         return self.qdcount
  335.  
  336.     
  337.     def get_ancount(self):
  338.         return self.ancount
  339.  
  340.     
  341.     def get_nscount(self):
  342.         return self.nscount
  343.  
  344.     
  345.     def get_arcount(self):
  346.         return self.arcount
  347.  
  348.     
  349.     def rawData(self):
  350.         secondWord = self.opcode << 11
  351.         secondWord = secondWord | self.nm_flags << 4
  352.         secondWord = secondWord | self.rcode
  353.         data = pack('!HHHHHH', self.name_trn_id, secondWord, self.qdcount, self.ancount, self.nscount, self.arcount) + self.questions + self.answers
  354.         return data
  355.  
  356.     
  357.     def get_answers(self):
  358.         return self.answers
  359.  
  360.  
  361.  
  362. class NBHostEntry:
  363.     
  364.     def __init__(self, nbname, nametype, ip):
  365.         self._NBHostEntry__nbname = nbname
  366.         self._NBHostEntry__nametype = nametype
  367.         self._NBHostEntry__ip = ip
  368.  
  369.     
  370.     def get_nbname(self):
  371.         return self._NBHostEntry__nbname
  372.  
  373.     
  374.     def get_nametype(self):
  375.         return self._NBHostEntry__nametype
  376.  
  377.     
  378.     def get_ip(self):
  379.         return self._NBHostEntry__ip
  380.  
  381.     
  382.     def __repr__(self):
  383.         return '<NBHostEntry instance: NBname="' + self._NBHostEntry__nbname + '", IP="' + self._NBHostEntry__ip + '">'
  384.  
  385.  
  386.  
  387. class NBNodeEntry:
  388.     
  389.     def __init__(self, nbname, nametype, flags):
  390.         self._NBNodeEntry__nbname = string.ljust(nbname, 17)
  391.         self._NBNodeEntry__nametype = nametype
  392.         self._NBNodeEntry__flags = flags
  393.         self._NBNodeEntry__isgroup = flags & 32768
  394.         self._NBNodeEntry__nodetype = flags & 24576
  395.         self._NBNodeEntry__deleting = flags & 4096
  396.         self._NBNodeEntry__isconflict = flags & 2048
  397.         self._NBNodeEntry__isactive = flags & 1024
  398.         self._NBNodeEntry__ispermanent = flags & 512
  399.  
  400.     
  401.     def get_nbname(self):
  402.         return self._NBNodeEntry__nbname
  403.  
  404.     
  405.     def get_nametype(self):
  406.         return self._NBNodeEntry__nametype
  407.  
  408.     
  409.     def is_group(self):
  410.         return self._NBNodeEntry__isgroup
  411.  
  412.     
  413.     def get_nodetype(self):
  414.         return self._NBNodeEntry__nodetype
  415.  
  416.     
  417.     def is_deleting(self):
  418.         return self._NBNodeEntry__deleting
  419.  
  420.     
  421.     def is_conflict(self):
  422.         return self._NBNodeEntry__isconflict
  423.  
  424.     
  425.     def is_active(self):
  426.         return self._NBNodeEntry__isactive
  427.  
  428.     
  429.     def is_permanent(self):
  430.         return self._NBNodeEntry__ispermanent
  431.  
  432.     
  433.     def set_nbname(self, name):
  434.         self._NBNodeEntry__nbname = string.ljust(name, 17)
  435.  
  436.     
  437.     def set_nametype(self, type):
  438.         self._NBNodeEntry__nametype = type
  439.  
  440.     
  441.     def set_flags(self, flags):
  442.         self._NBNodeEntry__flags = flags
  443.  
  444.     
  445.     def __repr__(self):
  446.         s = '<NBNodeEntry instance: NBname="' + self._NBNodeEntry__nbname + '" NameType="' + NAME_TYPES[self._NBNodeEntry__nametype] + '"'
  447.         if self._NBNodeEntry__isactive:
  448.             s = s + ' ACTIVE'
  449.         
  450.         if self._NBNodeEntry__isgroup:
  451.             s = s + ' GROUP'
  452.         
  453.         if self._NBNodeEntry__isconflict:
  454.             s = s + ' CONFLICT'
  455.         
  456.         if self._NBNodeEntry__deleting:
  457.             s = s + ' DELETING'
  458.         
  459.         return s
  460.  
  461.     
  462.     def rawData(self):
  463.         return self._NBNodeEntry__nbname + pack('!BH', self._NBNodeEntry__nametype, self._NBNodeEntry__flags)
  464.  
  465.  
  466.  
  467. class NetBIOS:
  468.     
  469.     def __init__(self, servport = NETBIOS_NS_PORT):
  470.         s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  471.         has_bind = 1
  472.         for i in range(0, 10):
  473.             
  474.             try:
  475.                 s.bind((INADDR_ANY, randint(10000, 60000)))
  476.                 s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
  477.                 has_bind = 1
  478.             continue
  479.             except socket.error:
  480.                 ex = None
  481.                 continue
  482.             
  483.  
  484.         
  485.         if not has_bind:
  486.             raise NetBIOSError, ('Cannot bind to a good UDP port', ERRCLASS_OS, errno.EAGAIN)
  487.         
  488.         self._NetBIOS__sock = s
  489.         self._NetBIOS__servport = NETBIOS_NS_PORT
  490.         self._NetBIOS__nameserver = None
  491.         self._NetBIOS__broadcastaddr = BROADCAST_ADDR
  492.         self.mac = '00-00-00-00-00-00'
  493.  
  494.     
  495.     def set_nameserver(self, nameserver):
  496.         self._NetBIOS__nameserver = nameserver
  497.  
  498.     
  499.     def get_nameserver(self):
  500.         return self._NetBIOS__nameserver
  501.  
  502.     
  503.     def set_broadcastaddr(self, broadcastaddr):
  504.         self._NetBIOS__broadcastaddr = broadcastaddr
  505.  
  506.     
  507.     def get_broadcastaddr(self):
  508.         return self._NetBIOS__broadcastaddr
  509.  
  510.     
  511.     def gethostbyname(self, nbname, type = TYPE_WORKSTATION, scope = None, timeout = 1):
  512.         return self._NetBIOS__queryname(nbname, self._NetBIOS__nameserver, type, scope, timeout)
  513.  
  514.     
  515.     def getnodestatus(self, nbname, destaddr = None, type = TYPE_WORKSTATION, scope = None, timeout = 1):
  516.         if destaddr:
  517.             return self._NetBIOS__querynodestatus(nbname, destaddr, type, scope, timeout)
  518.         else:
  519.             return self._NetBIOS__querynodestatus(nbname, self._NetBIOS__nameserver, type, scope, timeout)
  520.  
  521.     
  522.     def getmacaddress(self):
  523.         return self.mac
  524.  
  525.     
  526.     def __queryname(self, nbname, destaddr, type, scope, timeout):
  527.         netbios_name = string.upper(nbname)
  528.         trn_id = randint(1, 32000)
  529.         p = NetBIOSPacket()
  530.         p.set_trn_id(trn_id)
  531.         netbios_name = string.upper(nbname)
  532.         qn_label = encode_name(netbios_name, type, scope)
  533.         p.addQuestion(qn_label, QUESTION_TYPE_NB, QUESTION_CLASS_IN)
  534.         qn_label = encode_name(netbios_name, type, scope)
  535.         if not destaddr:
  536.             p.set_nm_flags(NM_FLAGS_BROADCAST)
  537.             destaddr = self._NetBIOS__broadcastaddr
  538.         
  539.         wildcard_query = netbios_name == '*'
  540.         req = p.rawData()
  541.         self._NetBIOS__sock.sendto(req, 0, (destaddr, self._NetBIOS__servport))
  542.         addrs = []
  543.         tries = 3
  544.         while None:
  545.             
  546.             try:
  547.                 (ready, _, _) = select.select([
  548.                     self._NetBIOS__sock.fileno()], [], [], timeout)
  549.                 if not ready:
  550.                     if tries and not wildcard_query:
  551.                         self._NetBIOS__sock.sendto(req, 0, (destaddr, self._NetBIOS__servport))
  552.                         tries = tries - 1
  553.                     elif wildcard_query:
  554.                         return addrs
  555.                     else:
  556.                         raise NetBIOSTimeout
  557.                 else:
  558.                     (data, _) = self._NetBIOS__sock.recvfrom(65536, 0)
  559.                     res = NetBIOSPacket(data)
  560.                     if res.get_trn_id() == p.get_trn_id():
  561.                         if res.get_rcode():
  562.                             if res.get_rcode() == 3:
  563.                                 return None
  564.                             else:
  565.                                 raise NetBIOSError, ('Negative name query response', ERRCLASS_QUERY, res.get_rcode())
  566.                         
  567.                         answ = NBPositiveNameQueryResponse(res.get_answers())
  568.                         if not wildcard_query:
  569.                             return addrs
  570.                         
  571.                 except select.error:
  572.                     ready
  573.                     ex = ready
  574.                     if ex[0] != errno.EINTR and ex[0] != errno.EAGAIN:
  575.                         raise NetBIOSError, ('Error occurs while waiting for response', ERRCLASS_OS, ex[0])
  576.                     
  577.                     ex[0] != errno.EAGAIN
  578.                     except socket.error:
  579.                         ex = None
  580.                         continue
  581.                     
  582.                     None<EXCEPTION MATCH>socket.error
  583.             return None
  584.  
  585.  
  586.     
  587.     def __querynodestatus(self, nbname, destaddr, type, scope, timeout):
  588.         trn_id = randint(1, 32000)
  589.         p = NetBIOSPacket()
  590.         p.set_trn_id(trn_id)
  591.         netbios_name = string.upper(nbname)
  592.         qn_label = encode_name(netbios_name, type, scope)
  593.         p.addQuestion(qn_label, QUESTION_TYPE_NBSTAT, QUESTION_CLASS_IN)
  594.         if not destaddr:
  595.             p.set_nm_flags(NM_FLAGS_BROADCAST)
  596.             destaddr = self._NetBIOS__broadcastaddr
  597.         
  598.         req = p.rawData()
  599.         tries = 3
  600.         while None:
  601.             
  602.             try:
  603.                 self._NetBIOS__sock.sendto(req, 0, (destaddr, self._NetBIOS__servport))
  604.                 (ready, _, _) = select.select([
  605.                     self._NetBIOS__sock.fileno()], [], [], timeout)
  606.                 if not ready:
  607.                     if tries:
  608.                         tries = tries - 1
  609.                     else:
  610.                         raise NetBIOSTimeout
  611.                 else:
  612.                     
  613.                     try:
  614.                         (data, _) = self._NetBIOS__sock.recvfrom(65536, 0)
  615.                     except:
  616.                         return None
  617.  
  618.                     res = NetBIOSPacket(data)
  619.                     if res.get_trn_id() == p.get_trn_id():
  620.                         if res.get_rcode():
  621.                             if res.get_rcode() == 3:
  622.                                 return None
  623.                             else:
  624.                                 raise NetBIOSError, ('Negative name query response', ERRCLASS_QUERY, res.get_rcode())
  625.                         
  626.                         answ = NBNodeStatusResponse(res.get_answers())
  627.                         self.mac = answ.get_mac()
  628.                         return answ.get_node_names()
  629.                 except select.error:
  630.                     ready
  631.                     ex = ready
  632.                     if ex[0] != errno.EINTR and ex[0] != errno.EAGAIN:
  633.                         raise NetBIOSError, ('Error occurs while waiting for response', ERRCLASS_OS, ex[0])
  634.                     
  635.                     ex[0] != errno.EAGAIN
  636.                     except socket.error:
  637.                         ex = None
  638.                         continue
  639.                     
  640.                     None<EXCEPTION MATCH>socket.error
  641.             return None
  642.  
  643.  
  644.  
  645.  
  646. def encode_name(name, type, scope):
  647.     if name == '*':
  648.         name = name + '\x00' * 15
  649.     elif len(name) > 15:
  650.         name = name[:15] + chr(type)
  651.     else:
  652.         name = string.ljust(name, 15) + chr(type)
  653.     encoded_name = chr(len(name) * 2) + re.sub('.', _do_first_level_encoding, name)
  654.     if scope:
  655.         encoded_scope = ''
  656.         for s in string.split(scope, '.'):
  657.             encoded_scope = encoded_scope + chr(len(s)) + s
  658.         
  659.         return encoded_name + encoded_scope + '\x00'
  660.     else:
  661.         return encoded_name + '\x00'
  662.  
  663.  
  664. def _do_first_level_encoding(m):
  665.     s = ord(m.group(0))
  666.     return string.uppercase[s >> 4] + string.uppercase[s & 15]
  667.  
  668.  
  669. def decode_name(name):
  670.     name_length = ord(name[0])
  671.     if not name_length == 32:
  672.         raise AssertionError
  673.     decoded_name = re.sub('..', _do_first_level_decoding, name[1:33])
  674.     if name[33] == '\x00':
  675.         return (34, decoded_name, '')
  676.     else:
  677.         decoded_domain = ''
  678.         offset = 34
  679.         while None:
  680.             domain_length = ord(name[offset])
  681.             if domain_length == 0:
  682.                 break
  683.             
  684.             decoded_domain = '.' + name[offset:offset + domain_length]
  685.             offset = offset + domain_length
  686.         return (offset + 1, decoded_name, decoded_domain)
  687.  
  688.  
  689. def _do_first_level_decoding(m):
  690.     s = m.group(0)
  691.     return chr(ord(s[0]) - ord('A') << 4 | ord(s[1]) - ord('A'))
  692.  
  693.  
  694. class NetBIOSSessionPacket:
  695.     
  696.     def __init__(self, data = 0):
  697.         self.type = 0
  698.         self.flags = 0
  699.         self.length = 0
  700.         if data == 0:
  701.             self._trailer = ''
  702.         else:
  703.             
  704.             try:
  705.                 self.type = ord(data[0])
  706.                 self.flags = ord(data[1])
  707.                 self.length = unpack('!H', data[2:4])[0]
  708.                 self._trailer = data[4:]
  709.             except:
  710.                 raise NetBIOSError('Wrong packet format ')
  711.  
  712.  
  713.     
  714.     def set_type(self, type):
  715.         self.type = type
  716.  
  717.     
  718.     def get_type(self):
  719.         return self.type
  720.  
  721.     
  722.     def rawData(self):
  723.         data = pack('!BBH', self.type, self.flags, self.length) + self._trailer
  724.         return data
  725.  
  726.     
  727.     def set_trailer(self, data):
  728.         self._trailer = data
  729.         self.length = len(data)
  730.  
  731.     
  732.     def get_length(self):
  733.         return self.length
  734.  
  735.     
  736.     def get_trailer(self):
  737.         return self._trailer
  738.  
  739.  
  740.  
  741. class NetBIOSSession:
  742.     
  743.     def __init__(self, myname, remote_name, remote_host, remote_type = TYPE_SERVER, sess_port = NETBIOS_SESSION_PORT, timeout = None, local_type = TYPE_WORKSTATION):
  744.         if len(myname) > 15:
  745.             self._NetBIOSSession__myname = string.upper(myname[:15])
  746.         else:
  747.             self._NetBIOSSession__myname = string.upper(myname)
  748.         if not remote_name:
  749.             raise AssertionError
  750.         if len(remote_name) > 15:
  751.             self._NetBIOSSession__remote_name = string.upper(remote_name[:15])
  752.         else:
  753.             self._NetBIOSSession__remote_name = string.upper(remote_name)
  754.         self._NetBIOSSession__remote_host = remote_host
  755.         self._NetBIOSSession__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  756.         
  757.         try:
  758.             self._NetBIOSSession__sock.connect((remote_host, sess_port))
  759.         except socket.error:
  760.             ex = None
  761.             raise ex
  762.  
  763.         if sess_port == NETBIOS_SESSION_PORT:
  764.             self._NetBIOSSession__request_session(remote_type, local_type, timeout)
  765.         
  766.  
  767.     
  768.     def get_myname(self):
  769.         return self._NetBIOSSession__myname
  770.  
  771.     
  772.     def get_remote_host(self):
  773.         return self._NetBIOSSession__remote_host
  774.  
  775.     
  776.     def get_remote_name(self):
  777.         return self._NetBIOSSession__remote_name
  778.  
  779.     
  780.     def close(self):
  781.         self._NetBIOSSession__sock.close()
  782.  
  783.     
  784.     def send_packet(self, data):
  785.         p = NetBIOSSessionPacket()
  786.         p.set_type(NETBIOS_SESSION_MESSAGE)
  787.         p.set_trailer(data)
  788.         self._NetBIOSSession__sock.send(p.rawData())
  789.  
  790.     
  791.     def recv_packet(self, timeout = None):
  792.         data = self._NetBIOSSession__read(timeout)
  793.         return NetBIOSSessionPacket(data)
  794.  
  795.     
  796.     def __request_session(self, remote_type, local_type, timeout = None):
  797.         p = NetBIOSSessionPacket()
  798.         remote_name = encode_name(self._NetBIOSSession__remote_name, remote_type, '')
  799.         myname = encode_name(self._NetBIOSSession__myname, local_type, '')
  800.         p.set_type(NETBIOS_SESSION_REQUEST)
  801.         p.set_trailer(remote_name + myname)
  802.         self._NetBIOSSession__sock.send(p.rawData())
  803.         while None:
  804.             p = self.recv_packet(timeout)
  805.             if p.get_type() == NETBIOS_SESSION_NEGATIVE_RESPONSE:
  806.                 raise NetBIOSError, ('Cannot request session', ERRCLASS_SESSION, ord(p.get_trailer()[0]))
  807.                 continue
  808.             if p.get_type() == NETBIOS_SESSION_POSITIVE_RESPONSE:
  809.                 break
  810.                 continue
  811.  
  812.     
  813.     def __read(self, timeout = None):
  814.         read_len = 4
  815.         data = ''
  816.         while read_len > 0:
  817.             
  818.             try:
  819.                 (ready, _, _) = select.select([
  820.                     self._NetBIOSSession__sock.fileno()], [], [], timeout)
  821.                 if not ready:
  822.                     raise NetBIOSTimeout
  823.                 
  824.                 received = self._NetBIOSSession__sock.recv(read_len)
  825.                 if len(received) == 0:
  826.                     raise NetBIOSError, ('Error while reading from remote', ERRCLASS_OS, None)
  827.                 
  828.                 data = data + received
  829.                 read_len = 4 - len(data)
  830.             continue
  831.             except select.error:
  832.                 ex = None
  833.                 if ex[0] != errno.EINTR and ex[0] != errno.EAGAIN:
  834.                     raise NetBIOSError, ('Error occurs while reading from remote', ERRCLASS_OS, ex[0])
  835.                 
  836.                 ex[0] != errno.EAGAIN
  837.             
  838.  
  839.             None<EXCEPTION MATCH>select.error
  840.         (type, flags, length) = unpack('>ccH', data)
  841.         if ord(flags) & 1:
  842.             length = length | 65536
  843.         
  844.         read_len = length
  845.         data2 = ''
  846.         while read_len > 0:
  847.             
  848.             try:
  849.                 (ready, _, _) = select.select([
  850.                     self._NetBIOSSession__sock.fileno()], [], [], timeout)
  851.                 if not ready:
  852.                     raise NetBIOSTimeout
  853.                 
  854.                 received = self._NetBIOSSession__sock.recv(read_len)
  855.                 if len(received) == 0:
  856.                     raise NetBIOSError, ('Error while reading from remote', ERRCLASS_OS, None)
  857.                 
  858.                 data2 = data2 + received
  859.                 read_len = length - len(data2)
  860.             continue
  861.             except select.error:
  862.                 ex = None
  863.                 if ex[0] != errno.EINTR and ex[0] != errno.EAGAIN:
  864.                     raise NetBIOSError, ('Error while reading from remote', ERRCLASS_OS, ex[0])
  865.                 
  866.                 ex[0] != errno.EAGAIN
  867.             
  868.  
  869.             None<EXCEPTION MATCH>select.error
  870.         return data + data2
  871.  
  872.     
  873.     def get_socket(self):
  874.         return self._NetBIOSSession__sock
  875.  
  876.  
  877. ERRCLASS_QUERY = 0
  878. ERRCLASS_SESSION = 240
  879. ERRCLASS_OS = 255
  880. QUERY_ERRORS = {
  881.     1: 'Request format error. Please file a bug report.',
  882.     2: 'Internal server error',
  883.     3: 'Name does not exist',
  884.     4: 'Unsupported request',
  885.     5: 'Request refused' }
  886. SESSION_ERRORS = {
  887.     128: 'Not listening on called name',
  888.     129: 'Not listening for calling name',
  889.     130: 'Called name not present',
  890.     131: 'Sufficient resources',
  891.     143: 'Unspecified error' }
  892.  
  893. def main():
  894.     print 
  895.  
  896. if __name__ == '__main__':
  897.     main()
  898.  
  899.